#include "solver.h"

Solver::Solver(int size)
{
    this->size=size;
    isGameEnd=false;
    //indeks 0,1 buat gerakan dam hitam. 2,3 untuk dam putih. King pake semuanya
    dr={-1,-1,1,1};
    dc={-1,1,-1,1};

    //inisialisasi board
    setBoardSize(size);
    if (size==8){
        for(int i=0;i<8;++i) if(i%2==1) board[0][i]=0; else board[0][i]=2;
        for(int i=0;i<8;++i) if(i%2==1) board[1][i]=2; else board[1][i]=0;
        for(int i=0;i<8;++i) if(i%2==1) board[2][i]=0; else board[2][i]=2;
        for(int i=0;i<8;++i) if(i%2==1) board[3][i]=1; else board[3][i]=0;
        for(int i=0;i<8;++i) if(i%2==1) board[4][i]=0; else board[4][i]=1;
        for(int i=0;i<8;++i) if(i%2==1) board[5][i]=4; else board[5][i]=0;
        for(int i=0;i<8;++i) if(i%2==1) board[6][i]=0; else board[6][i]=4;
        for(int i=0;i<8;++i) if(i%2==1) board[7][i]=4; else board[7][i]=0;
    } else if(size==10){
        for(int i=0;i<10;++i) if(i%2==1) board[0][i]=0; else board[0][i]=2;
        for(int i=0;i<10;++i) if(i%2==1) board[1][i]=2; else board[1][i]=0;
        for(int i=0;i<10;++i) if(i%2==1) board[2][i]=0; else board[2][i]=2;
        for(int i=0;i<10;++i) if(i%2==1) board[3][i]=2; else board[3][i]=0;
        for(int i=0;i<10;++i) if(i%2==1) board[4][i]=0; else board[4][i]=1;
        for(int i=0;i<10;++i) if(i%2==1) board[5][i]=1; else board[5][i]=0;
        for(int i=0;i<10;++i) if(i%2==1) board[6][i]=0; else board[6][i]=4;
        for(int i=0;i<10;++i) if(i%2==1) board[7][i]=4; else board[7][i]=0;
        for(int i=0;i<10;++i) if(i%2==1) board[8][i]=0; else board[8][i]=4;
        for(int i=0;i<10;++i) if(i%2==1) board[9][i]=4; else board[9][i]=0;
    }
}

Solver::~Solver()
{
    //deallocate something here
    free(board);
}

int** Solver::getBoard()
{
    return board;
}

void Solver::moveByGreedyTypeOne(int playerid,int size,bool* isstillturn,int* movetype,bool* gerak)
{
    //AI serang: maju terus pantang mundur
    *gerak=false;
    *isstillturn=false;

    if(playerid==ID_PLAYER_HITAM){
        //LANGKAH 1: yang bisa dimakan, makanlah
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_HITAM || this->board[i][j] == ID_PLAYER_HITAM_RAJA){
                    int adj=2;
                    if(this->board[i][j] == ID_PLAYER_HITAM_RAJA)
                        adj=4;
                    for(int k=0;k<adj;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            (this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_PUTIH || this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_PUTIH_RAJA) &&
                            i+2*dr[k]>=0 && i+2*dr[k]<size && j+2*dc[k]>=0 && j+2*dc[k]<size &&
                            this->board[i+2*dr[k]][j+2*dc[k]] == 1
                            ){
                                *gerak=true;
                                *movetype=1;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+2*dr[k],j+2*dc[k]);
                                this->board[i+2*dr[k]][j+2*dc[k]]=this->board[i][j];
                                this->board[i+dr[k]][j+dc[k]]=1;
                                this->board[i][j]=1;

                                int rnow=i+2*dr[k];
                                int cnow=j+2*dc[k];

                                if(rnow == 0){
                                    this->board[rnow][cnow]=ID_PLAYER_HITAM_RAJA;
                                    goto blackgreedyfrontdone;
                                }

                                for(int l=0;l<adj;++l){
                                    if( rnow+dr[k]>=0 && rnow+dr[k]<size && cnow+dc[k]>=0 && cnow+dc[k]<size &&
                                        (this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH || this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH_RAJA) &&
                                        rnow+2*dr[k]>=0 && rnow+2*dr[k]<size && cnow+2*dc[k]>=0 && cnow+2*dc[k]<size &&
                                        this->board[rnow+2*dr[k]][cnow+2*dc[k]] == 1
                                        )
                                    *isstillturn=true;
                                }

                                goto blackgreedyfrontdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 2: majukan dam terdepan dimana kalo kita dimakan kita punya backup
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j]==ID_PLAYER_HITAM){
                    int adj=2;
                    for(int k=0;k<adj;++k){
                        if(i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k] < size && this->board[i+dr[k]][j+dc[k]] == 1){
                            for(int l=2;l<4;++l){
                                if(i+dr[l]>=0 && i+dr[l]<size && j+dc[l]>=0 && j+dc[l]<size &&
                                   (this->board[i+dr[l]][j+dc[l]] == ID_PLAYER_HITAM || this->board[i+dr[l]][j+dc[l]] == ID_PLAYER_HITAM_RAJA)
                                   ){
                                        *gerak=true;
                                        *movetype=0;
                                        this->source = wxPoint(i,j);
                                        this->dest = wxPoint(i+dr[k],j+dc[k]);
                                        this->board[i+dr[k]][j+dc[k]]=this->board[i][j];
                                        this->board[i][j]=1;

                                        if(i+dr[k] == 0){
                                            this->board[i+dr[k]][j+dc[k]]=ID_PLAYER_HITAM_RAJA;
                                        }

                                        goto blackgreedyfrontdone;
                                    }
                            }
                        }
                    }
                }
            }
        }

        //LANGKAH 3: kalo gak ada yang punya backup, terpaksa majuin yg paling depan
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_HITAM){
                    int adj=2;
                    for(int k=0;k<adj;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            this->board[i+dr[k]][j+dc[k]]==1
                            ){
                                *gerak=true;
                                *movetype=0;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+dr[k],j+dc[k]);
                                int rnow=i+dr[k];
                                int cnow=j+dc[k];
                                this->board[i+dr[k]][j+dc[k]]=this->board[i][j];
                                this->board[i][j]=1;

                                if(rnow==0){
                                    this->board[rnow][cnow]=ID_PLAYER_HITAM_RAJA;
                                }

                                goto blackgreedyfrontdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 4: handle gerakan raja
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_HITAM_RAJA){
                    for(int k=0;k<size;++k){
                        for(int l=0;l<size;++l){
                                if(this->board[k][l]== ID_PLAYER_PUTIH || this->board[k][l]== ID_PLAYER_PUTIH_RAJA ){
                                    if(k<i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k<i && l==j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        } else if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k<i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k==i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        } else if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k==i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k>i && l<j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k>i && l==j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    } else if(k>i && l>j){
                                        if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedyfrontdone;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }

        blackgreedyfrontdone:
        1==1;//dummy statement;

    } else if(playerid==ID_PLAYER_PUTIH){
        //LANGKAH 1: yang bisa dimakan, makanlah
        for(int i=size-1;i>=0;--i){
            for(int j=size-1;j>=0;--j){
                if(this->board[i][j] == ID_PLAYER_PUTIH || this->board[i][j] == ID_PLAYER_PUTIH_RAJA){
                    int adj=2;
                    if(this->board[i][j] == ID_PLAYER_PUTIH_RAJA)
                        adj=0;
                    for(int k=adj;k<4;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            (this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_HITAM || this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_HITAM_RAJA) &&
                            i+2*dr[k]>=0 && i+2*dr[k]<size && j+2*dc[k]>=0 && j+2*dc[k]<size &&
                            this->board[i+2*dr[k]][j+2*dc[k]] == 1
                            ){
                                *gerak=true;
                                *movetype=1;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+2*dr[k],j+2*dc[k]);
                                this->board[i+2*dr[k]][j+2*dc[k]]=this->board[i][j];
                                this->board[i+dr[k]][j+dc[k]]=1;
                                this->board[i][j]=1;

                                int rnow=i+2*dr[k];
                                int cnow=j+2*dc[k];

                                if(rnow == size-1) {
                                    this->board[rnow][cnow]=ID_PLAYER_PUTIH_RAJA;
                                    goto whitegreedyfrontdone;
                                }

                                for(int l=adj;l<4;++l){
                                    if( rnow+dr[k]>=0 && rnow+dr[k]<size && cnow+dc[k]>=0 && cnow+dc[k]<size &&
                                        (this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH || this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH_RAJA) &&
                                        rnow+2*dr[k]>=0 && rnow+2*dr[k]<size && cnow+2*dc[k]>=0 && cnow+2*dc[k]<size &&
                                        this->board[rnow+2*dr[k]][cnow+2*dc[k]] == 1
                                        )
                                    *isstillturn=true;
                                }
                                goto whitegreedyfrontdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 2: majukan dam terdepan dimana kalo kita dimakan kita punya backup
        for(int i=size-1;i>=0;--i){
            for(int j=size;j>=0;--j){
                if(this->board[i][j]==ID_PLAYER_PUTIH){
                    for(int k=2;k<4;++k){
                        if(i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k] < size && this->board[i+dr[k]][j+dc[k]] == 1){
                            for(int l=0;l<2;++l){
                                if(i+dr[l]>=0 && i+dr[l]<size && j+dc[l]>=0 && j+dc[l]<size &&
                                   (this->board[i+dr[l]][j+dc[l]] == ID_PLAYER_PUTIH || this->board[i+dr[l]][j+dc[l]] == ID_PLAYER_PUTIH_RAJA)
                                   ){
                                        *gerak=true;
                                        *movetype=0;
                                        this->source = wxPoint(i,j);
                                        this->dest = wxPoint(i+dr[k],j+dc[k]);
                                        this->board[i+dr[k]][j+dc[k]]=this->board[i][j];
                                        this->board[i][j]=1;

                                        if(i+dr[k] == size-1){
                                            this->board[i+dr[k]][j+dc[k]]=ID_PLAYER_PUTIH_RAJA;
                                        }

                                        goto whitegreedyfrontdone;
                                    }
                            }
                        }
                    }
                }
            }
        }

        //LANGKAH 3: handle gerakan dam biasa
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_PUTIH){
                    int adj=2;
                    for(int k=adj;k<4;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            this->board[i+dr[k]][j+dc[k]]==1
                            ){
                                *gerak=true;
                                *movetype=0;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+dr[k],j+dc[k]);
                                int rnow=i+dr[k];
                                int cnow=j+dc[k];

                                this->board[i+dr[k]][j+dc[k]]=this->board[i][j];
                                this->board[i][j]=1;

                                if(rnow==size-1){
                                    this->board[rnow][cnow]=ID_PLAYER_PUTIH_RAJA;
                                }

                                goto whitegreedyfrontdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 3: handle gerakan raja
        for(int i=size-1;i>=0;--i){
            for(int j=size-1;j>=0;--j){
                if(this->board[i][j] == ID_PLAYER_PUTIH_RAJA){
                    for(int k=0;k<size;++k){
                        for(int l=0;l<size;++l){
                                if(this->board[k][l]== ID_PLAYER_HITAM || this->board[k][l]== ID_PLAYER_HITAM_RAJA){
                                    if(k<i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k<i && l==j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        } else if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k<i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k==i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        } else if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k==i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k>i && l<j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k>i && l==j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    } else if(k>i && l>j){
                                        if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedyfrontdone;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }

        whitegreedyfrontdone:
        1==1;//dummy statement;
    }
}

void Solver::moveByGreedyTypeTwo(int playerid,int size,bool* isstillturn,int* movetype,bool* gerak)
{
    //AI defense: makan yang bisa dimakan, kalo tidak ada, gerakin dam majukan dam paling belakang
    //movetype 0=move biasa, 1=eat;
    *gerak=false;
    *isstillturn=false;
    if(playerid==ID_PLAYER_HITAM){ //GERAKAN DAM HITAM
        //LANGKAH 1: yang bisa dimakan, makanlah
        for(int i=size-1;i>=0;--i){
            for(int j=size-1;j>=0;--j){
                if(this->board[i][j] == ID_PLAYER_HITAM || this->board[i][j] == ID_PLAYER_HITAM_RAJA){
                    int adj=2;
                    if(this->board[i][j] == ID_PLAYER_HITAM_RAJA)
                        adj=4;
                    for(int k=0;k<adj;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            (this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_PUTIH || this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_PUTIH_RAJA) &&
                            i+2*dr[k]>=0 && i+2*dr[k]<size && j+2*dc[k]>=0 && j+2*dc[k]<size &&
                            this->board[i+2*dr[k]][j+2*dc[k]] == 1
                            ){
                                *gerak=true;
                                *movetype=1;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+2*dr[k],j+2*dc[k]);
                                this->board[i+2*dr[k]][j+2*dc[k]]=this->board[i][j];
                                this->board[i+dr[k]][j+dc[k]]=1;
                                this->board[i][j]=1;

                                int rnow=i+2*dr[k];
                                int cnow=j+2*dc[k];

                                if(rnow == 0){
                                    this->board[rnow][cnow]=ID_PLAYER_HITAM_RAJA;
                                    goto blackgreedybackdone;
                                }

                                for(int l=0;l<adj;++l){
                                    if( rnow+dr[k]>=0 && rnow+dr[k]<size && cnow+dc[k]>=0 && cnow+dc[k]<size &&
                                        (this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH || this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH_RAJA) &&
                                        rnow+2*dr[k]>=0 && rnow+2*dr[k]<size && cnow+2*dc[k]>=0 && cnow+2*dc[k]<size &&
                                        this->board[rnow+2*dr[k]][cnow+2*dc[k]] == 1
                                        )
                                    *isstillturn=true;
                                }

                                goto blackgreedybackdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 2: handle gerakan dam biasa
        for(int i=size-1;i>=0;--i){
            for(int j=size-1;j>=0;--j){
                if(this->board[i][j] == ID_PLAYER_HITAM){
                    int adj=2;
                    for(int k=0;k<adj;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            this->board[i+dr[k]][j+dc[k]]==1
                            ){
                                *gerak=true;
                                *movetype=0;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+dr[k],j+dc[k]);
                                int rnow=i+dr[k];
                                int cnow=j+dc[k];
                                this->board[i+dr[k]][j+dc[k]]=this->board[i][j];
                                this->board[i][j]=1;

                                if(rnow==0){
                                    this->board[rnow][cnow]=ID_PLAYER_HITAM_RAJA;
                                }

                                goto blackgreedybackdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 3: handle gerakan raja
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_HITAM_RAJA){
                    for(int k=0;k<size;++k){
                        for(int l=0;l<size;++l){
                                if(this->board[k][l]== ID_PLAYER_PUTIH || this->board[k][l]== ID_PLAYER_PUTIH_RAJA ){
                                    if(k<i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k<i && l==j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        } else if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k<i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k==i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        } else if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k==i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k>i && l<j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k>i && l==j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    } else if(k>i && l>j){
                                        if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto blackgreedybackdone;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }

        blackgreedybackdone:
        1==1;//dummy statement;

    } else { //GERAKAN DAM PUTIH
        //LANGKAH 1: yang bisa dimakan, makanlah
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_PUTIH || this->board[i][j] == ID_PLAYER_PUTIH_RAJA){
                    int adj=2;
                    if(this->board[i][j] == ID_PLAYER_PUTIH_RAJA)
                        adj=0;
                    for(int k=adj;k<4;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            (this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_HITAM || this->board[i+dr[k]][j+dc[k]] == ID_PLAYER_HITAM_RAJA) &&
                            i+2*dr[k]>=0 && i+2*dr[k]<size && j+2*dc[k]>=0 && j+2*dc[k]<size &&
                            this->board[i+2*dr[k]][j+2*dc[k]] == 1
                            ){
                                *gerak=true;
                                *movetype=1;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+2*dr[k],j+2*dc[k]);
                                this->board[i+2*dr[k]][j+2*dc[k]]=this->board[i][j];
                                this->board[i+dr[k]][j+dc[k]]=1;
                                this->board[i][j]=1;

                                int rnow=i+2*dr[k];
                                int cnow=j+2*dc[k];

                                if(rnow == size-1) {
                                    this->board[rnow][cnow]=ID_PLAYER_PUTIH_RAJA;
                                    goto whitegreedybackdone;
                                }

                                for(int l=adj;l<4;++l){
                                    if( rnow+dr[k]>=0 && rnow+dr[k]<size && cnow+dc[k]>=0 && cnow+dc[k]<size &&
                                        (this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH || this->board[rnow+dr[k]][cnow+dc[k]] == ID_PLAYER_PUTIH_RAJA) &&
                                        rnow+2*dr[k]>=0 && rnow+2*dr[k]<size && cnow+2*dc[k]>=0 && cnow+2*dc[k]<size &&
                                        this->board[rnow+2*dr[k]][cnow+2*dc[k]] == 1
                                        )
                                    *isstillturn=true;
                                }
                                goto whitegreedybackdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 2: handle gerakan dam biasa
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(this->board[i][j] == ID_PLAYER_PUTIH){
                    int adj=2;
                    for(int k=adj;k<4;++k){
                        if( i+dr[k]>=0 && i+dr[k]<size && j+dc[k]>=0 && j+dc[k]<size &&
                            this->board[i+dr[k]][j+dc[k]]==1
                            ){
                                *gerak=true;
                                *movetype=0;
                                this->source = wxPoint(i,j);
                                this->dest = wxPoint(i+dr[k],j+dc[k]);
                                int rnow=i+dr[k];
                                int cnow=j+dc[k];

                                this->board[i+dr[k]][j+dc[k]]=this->board[i][j];
                                this->board[i][j]=1;

                                if(rnow==size-1){
                                    this->board[rnow][cnow]=ID_PLAYER_PUTIH_RAJA;
                                }

                                goto whitegreedybackdone;
                            }
                    }
                }
            }
        }

        //LANGKAH 3: handle gerakan raja
        for(int i=size-1;i>=0;--i){
            for(int j=size-1;j>=0;--j){
                if(this->board[i][j] == ID_PLAYER_PUTIH_RAJA){
                    for(int k=0;k<size;++k){
                        for(int l=0;l<size;++l){
                                if(this->board[k][l]== ID_PLAYER_HITAM || this->board[k][l]== ID_PLAYER_HITAM_RAJA){
                                    if(k<i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k<i && l==j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        } else if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k<i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k==i && l<j){
                                        if(i-1 >= 0 && j-1 >= 0 && this->board[i-1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        } else if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k==i && l>j){
                                        if(i-1 >= 0 && j+1 < size && this->board[i-1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j+1);
                                            this->board[i-1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k>i && l<j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i-1,j-1);
                                            this->board[i-1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k>i && l==j){
                                        if(i+1 < size && j-1 >= 0 && this->board[i+1][j-1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j-1);
                                            this->board[i+1][j-1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        } else if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    } else if(k>i && l>j){
                                        if(i+1 < size && j+1 < size && this->board[i+1][j+1]==1){
                                            *gerak=true;
                                            *movetype=0;
                                            this->source = wxPoint(i,j);
                                            this->dest = wxPoint(i+1,j+1);
                                            this->board[i+1][j+1]=this->board[i][j];
                                            this->board[i][j]=1;
                                            goto whitegreedybackdone;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }

        whitegreedybackdone:
        1==1;//dummy statement;
    }
}

void Solver::debugBoard(int size)
{
    for(int i=0;i<size;++i){
        cout<<i<<"| ";
        for(int j=0;j<size;++j){
            cout<<board[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<"   ";
    for(int i=0;i<size;++i)
        cout<<"- ";
    cout<<endl;
    cout<<"   ";
    for(int i=0;i<size;++i)
        cout<<i<<" ";
    cout<<endl;
}

void Solver::setBoardSize(int n)
{
    board=(int**)malloc(n*sizeof(int));
    for(int i=0;i<n;++i)
    board[i]=(int*)malloc(n*sizeof(int));
}

void Solver::setCell(int cellid,int row,int col)
{
    board[row][col]=cellid;
}

void Solver::moveCell(int rf,int cf,int rt,int ct)
{
    board[rt][ct]=board[rf][cf];
    board[rf][cf]=1;
}

bool Solver::updateGameStatus(int size) //true: game ends!
{
    int cb=0,cw=0;
    for(int i=0;i<size;++i){
        for(int j=0;j<size;++j){
            if(board[i][j] == ID_PLAYER_HITAM || board[i][j] == ID_PLAYER_HITAM_RAJA){
                ++cb;
            } else if(board[i][j] == ID_PLAYER_PUTIH || board[i][j] == ID_PLAYER_PUTIH_RAJA){
                ++cw;
            }
        }
    }
    //cout<<cb<<" "<<cw<<endl;
    if(cb==0 || cw==0) return true;
    return false;
}

void Solver::tesPointer(wxPoint* p)
{
    p = new wxPoint(1,2);
    this->source = wxPoint(1,2);
}

wxPoint Solver::getSource()
{
    return source;
}

wxPoint Solver::getDest()
{
    return dest;
}

void Solver::setBoard(int **arr)
{
    int i,j;
    for(i=0;i<size;++i)
    {
        for(j=0;j<size;++j)
        {
            board[i][j]=arr[i][j];
        }
    }
}
